//web_data.h
#ifndef WEB_DATA_H
#define WEB_DATA_H
#include <string>
#include <unordered_map>
#include <memory>
#include <vector>

typedef struct 
{
    char* ptr;   // 内存块指针
    size_t size; // 内存块大小
    size_t newSize; //申请的空间大小
}MemBlock;

//======================Http==============================
enum HttpMethod
{
    GET,
    POST,
    PUT,
    DEL,
    OPTION,
    HEAD,
    PATH
};

class HttpData
{
public:
    virtual std::unordered_map<std::string, std::string> gerReqHeader() = 0;
    virtual std::vector<MemBlock> getReqBody() = 0;
    virtual void writeStatus(std::string respStatus) = 0;
    virtual void writeHeader(std::unordered_map<std::string, std::string> &respHeaders) = 0;
    virtual void send(std::string respBody) = 0;
    virtual void finalize() = 0;
};

//======================WS==============================
enum WSMethod
{
    UPGRADE,
    OPEN,
    MESSAGE,
    PING,
    PONG,
    CLOSE
};


struct WebUserData {
    WebUserData() : dynamicPtr(nullptr), isValid(false) {}
    ~WebUserData() {
        isValid = false;
    }
     // 提供 makeData 方法模板，支持可变参数
    template<typename T, typename... Args>
    void makeData(Args&&... args) {
        dynamicPtr = std::make_shared<T>(std::forward<Args>(args)...);
    }

    // 提供获取指针对象的方法模板
    template<typename T>
    T* getData() {
        return std::static_pointer_cast<T>(dynamicPtr).get();
    }
    // 使用智能指针代替裸指针
    std::shared_ptr<void> dynamicPtr;
    bool isValid;
    std::string userId;
    std::string reserveStr;
};


class WsData
{
public:
    virtual std::unordered_map<std::string, std::string> gerReqHeader() = 0;
    virtual std::vector<MemBlock> getReqBody() = 0;
    virtual WebUserData* getUserData() = 0;
    /*升级调用此函数*/
    virtual void upgrade(bool success) = 0;
    virtual void send(std::string respBody) = 0;
    virtual void send(char* pRespBody, size_t respLen) = 0;
    virtual void subscribe(std::string topic) = 0;
    virtual void unsubscribe(std::string topic) = 0;
    virtual void publish(std::string topic, std::string msg) = 0;
    virtual void finalize() = 0; 
};


enum CompressWSOption{
        /* These are not actual compression options */
        _COMPRESSOR_MASK = 0x00FF,
        _DECOMPRESSOR_MASK = 0x0F00,
        /* Disabled, shared, shared are "special" values */
        DISABLED = 0,
        SHARED_COMPRESSOR = 1,
        SHARED_DECOMPRESSOR = 1 << 8,
        /* Highest 4 bits describe decompressor */
        DECOMPRESSOR_32KB = 15 << 8,
        DECOMPRESSOR_16KB = 14 << 8,
        DECOMPRESSOR_8KB = 13 << 8,
        DECOMPRESSOR_4KB = 12 << 8,
        DECOMPRESSOR_2KB = 11 << 8,
        DECOMPRESSOR_1KB = 10 << 8,
        DECOMPRESSOR_512B = 9 << 8,
        /* Same as 32kb */
        DEDICATED_DECOMPRESSOR = 15 << 8,

        /* Lowest 8 bit describe compressor */
        COMPRESSOR_3KB = 9 << 4 | 1,
        COMPRESSOR_4KB = 9 << 4 | 2,
        COMPRESSOR_8KB = 10 << 4 | 3,
        COMPRESSOR_16KB = 11 << 4 | 4,
        COMPRESSOR_32KB = 12 << 4 | 5,
        COMPRESSOR_64KB = 13 << 4 | 6,
        COMPRESSOR_128KB = 14 << 4 | 7,
        COMPRESSOR_256KB = 15 << 4 | 8,
        /* Same as 256kb */
        COMPRESSOR = 15 << 4 | 8
    };


struct WebBehaviorConfig
{
    WebBehaviorConfig()
    {
        key_file_name = nullptr;
        cert_file_name = nullptr;
        passphrase = nullptr;
        dh_params_file_name = nullptr;
        ca_file_name = nullptr;
        ssl_ciphers = nullptr;
        ssl_prefer_low_memory_usage = 0;
        compression = CompressWSOption::DISABLED;
        maxPayloadLength = 16*1024;
        idleTimeout = 120;
        maxBackpressure = 64 * 1024;
        closeOnBackpressureLimit = false;
        resetIdleTimeoutOnSend = false;
        sendPingsAutomatically = true;
        maxLifetime = 0;
        storeSendFailMsg = false;
    }
    const char *key_file_name;
    const char *cert_file_name;
    const char *passphrase;
    const char *dh_params_file_name;
    const char *ca_file_name;
    const char *ssl_ciphers;
    int ssl_prefer_low_memory_usage;
    //---------------------------------------
    CompressWSOption compression;
    unsigned int maxPayloadLength;
    unsigned short idleTimeout;
    unsigned int maxBackpressure;
    bool closeOnBackpressureLimit;
    bool resetIdleTimeoutOnSend;
    bool sendPingsAutomatically;
    unsigned short maxLifetime;
    /*是否存储发送失败的消息，当负载小的时候会重发*/
    bool storeSendFailMsg;
};



#endif
